package com.swu.java.hc077.factory;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import com.swu.java.hc077.interestingModule.CalcInterestingModule;
import com.swu.java.hc077.ui.MyProgramUiDevise;

/**
 * 界面监听所在的类
 * 
 * @author Mc 备注：这里监听按钮事件，通过传入的按钮，添加监听事件，并且在这里
 *         就通过监听来给运算符添加标识，以便传入calclogicdeal中来处理
 */
public class FactoryListener implements ActionListener {
	private JTextField jTextField;
	private JButton jButton;
	private JLabel jLabelResult;
	private char mark;
	private JPanel[] jButtonForBinaryConversion;
	public static int i = 0;// 作为一个标志传给logicdeal
	public static int theEqualsMark=1;//但你运算完成（标志为点击=），把自变量theEqualsMark=-theEqualsMark操作，作为标志


	/**
	 * 工具类有参构造
	 * 
	 * @param jTextField
	 *            文本框
	 * @param jButton
	 *            按钮
	 * @param jlabel
	 *            jlabelresult,标签，存储结果的
	 * @param char mark=jbutton.gettext 标识
	 * @param jpanel
	 *            ...jpanels 可变长参数，目的在于由于开启进制转换需要传入一个jpanel，并且设置他的可见属性为真
	 *            但是这个参数不是所有监听都要用，所以采用可变长参数
	 * 
	 * 
	 *            备注：思路是，首先循环添加所有button 在创建一个工具类，工具类里加入监听， 并且在创建监听类时
	 *            加入有参构造，意在创建按钮时，把他通过监听构造传递过来 ，达到用循环创建按钮，单一监听处理多个类似事件的目的 .
	 *            之前那之所以不行的原因在于，当你循环创建button时，所有button标示符都一样
	 *            他们在创建并添加到panel，当本次循环结束，就被回收，所以没办法根据标示符去 区分每个button 并且得到他们的text
	 *            因此出现点击每个按钮，文本框都显示最后 一个字符，解决思路是：在创建之后立即把该button 传递到监听类去。当然你也可
	 *            以创建button数组来区分每个按钮，但是似乎提供类似的数组构建按钮的方法十分 有限
	 * 
	 */
	public FactoryListener(JTextField jTextField, JButton jButton,
			JLabel jLabelResult, char mark,
			JPanel... jButtonForBinaryConversion) {
		super();
		this.jTextField = jTextField;
		this.jButton = jButton;
		this.jLabelResult = jLabelResult;
		this.mark = mark;
		this.jButtonForBinaryConversion = jButtonForBinaryConversion;
	}


	/**
	 * 监听类 主管逻辑业务处理 备注: 这里卡住很久，不管用if 还是switch都没法执行到方法内部，而且不报错，找也找不到
	 * 浪费了我一个晚上，原因简单，我为了让按钮显示文本居中，所以在文本前加了一个空格 而在case语句后加的却是“1”，其实应该是“
	 * 1”。很小很烦的一个逻辑错误！！
	 */
	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub

		/**
		 * 考虑到如果不在监控时判断操作运算符类型，之后再想从string中判断，会比较麻烦 所以用一个static int
		 * i作为标志传给业务逻辑并且在监听到=时，重新把i赋值为0 注意：这里还遗留有一些问题，参考 -->技术难题
		 * 
		 * 本来打算用嵌套switch case但是这样会提高程序使用内存，降低效率，最终选择先用if判断，在用两个switch并联
		 * 关于if的实现，不得不感谢MyProgramUiDevise.prompt变量，这一点绝对是一个精华变量，尤其是static
		 * 
		 *其实最开始，我比较菜，一直搞不清这些监听该怎么布局，后来想放到一个switch里，但是这样实在很冗余，不美观
		 *于是我从最简单的方式考虑，分类，不错，就是分类，按照处理方式分类，这样的话就可以使用相同的变量或者方法
		 *所以我分了一下，总是要执行的代码， MyProgramUiDevise.prompt为true才执行的代码，
		 *于是把代码模块化了一下
		 */
		if (theEqualsMark!=1) {
			jTextField.setText("");
			theEqualsMark=-theEqualsMark;
		} 
		jTextField.setText(jTextField.getText() + mark);
		
		if (MyProgramUiDevise.prompt) {
			/**
			 * 以下是MyProgramUiDevise.prompt为true才执行的代码监听
			 * 
			 * 这里用i-=1是由考虑的，原因是，在箭头按钮那里处理有点问题，有时会出这样的错
			 * 2+3 然后你箭头两次（i此时=1）在-3（此时i+=2 i=3）3其实代表*就会出现2-3=6
			 *虽然做了简单处理 ，但是累计越大越会存在不确定性，所以这里选择往下减
			 *
			 */
			switch (mark) {
			case 'Ⅰ':
				i-=1;
				break;
			case 'Ⅱ':
				i-=2;
				break;
			case 'Ⅲ':
				i-=3;
				break;
			case 'Ⅳ':
				i-=4;
				break;
			case 'Ⅴ':
				i-=5;
				System.out.println("********************"+i);
				break;
			case 'Ⅵ':
				i-=6;
				break;
			}

		} 

		/**
		 * 以下是无论什么情况下都必须起作用的代码监听
		 */
		switch (mark) {
		
		case '+':
			i++;
			System.out.println(mark);
			break;
		case '-':
			i += 2;
			System.out.println(mark);
			break;
		case '*':
			i += 3;
			System.out.println(mark);
			break;
		case '/':
			i += 4;
			System.out.println(mark);
			break;
		case '^':
			i += 5;
			System.out.println(mark);
			break;
		case '%':
			i += 6;
			System.out.println(mark);
			break;
		
		case '←':
			jTextField.setText(jTextField.getText().substring(0,
					jTextField.getText().length() - 2));
			System.out.println(mark);
			break;

		case '=': // 添加一个功能，当你输入22=，显示22，而不是有提示框，思路和上面一样
			theEqualsMark=-theEqualsMark;
			
			CalcLogicDeal calcLogicDeal = new CalcLogicDeal(jTextField
					.getText().substring(0, jTextField.getText().length() - 1),
					i);
			System.out.println(i);
			String result = calcLogicDeal.CalcLogicDeal();

			CalcInterestingModule ca = new CalcInterestingModule(jLabelResult,
					result); // 这里传入lable和一个参数result来产生随机结果显示，

			// jLabelResult.setText("我猜是" + result + "  嘎嘎，猜对了"); 本来应该这么给结果赋值

			i = 0; // 标识归零
			System.out.println(i);
			break;
		case 'M':
			System.out.println("清空");// 测试代码
			/**
			 * 业务逻辑
			 */
			jTextField.setText(null);
			i = 0;// 这里本来没有这句代码，但是会出一个错，当你按下=如果报错了，那么这时的i不会被赋值为零，往往下次计算就会出错
			break;
		case '|':
			// 处理进制转换界面创建的代码，但是不能用default处理，因为defaule还会包含数字
			System.out.println(mark);
			/**
			 * 一个prompt用来判断具体事件
			 */
			// JOptionPane.showMessageDialog(null,
			// "亲，请按提示操作，进制转换不会涉及到运算符，输入数字，点击转换模式即可");
			if (MyProgramUiDevise.prompt) {
				jButtonForBinaryConversion[0].setVisible(false);
				jLabelResult.setText("技能冷却，暂时无法使用进制转换");
				MyProgramUiDevise.prompt = false;
			} else {
				jButtonForBinaryConversion[0].setVisible(true);
				jLabelResult.setText("丫的升级了，新增技能：进制转换");
				MyProgramUiDevise.prompt = true;
			}
			System.out.println(MyProgramUiDevise.prompt);
			jTextField.setText(null);
			break;
		}
	}
}
